/*--------------------------------------------------------------------------------
* Copyright (c) 2022,西北农林科技大学信息学院计算机科学系
* All rights reserved.
*
* 文件名称：main.c
* 文件标识：见配置管理计划书
* 摘要：生成EXCEL表格列名称字符串。
* 题目：EXCEL的列名称由类似A, B, C, ..., Z, AA, AB, AC, ..., AZ,
*       BA, BB, ..., ZZ, AAA, AAB,...等这样的字符串构成。
*
*       假设从0开始计数，则列0对应"A", 列1对应"B"，而列26对应"AA"。
*
*       请编写函数将指定的列编号转换为字符串表示的列名称，要求函数原型为：
*           char* get_excel_column_name(char *col_name, int idx);
*       其输入/输出关系如：
*       Input          Output
*        26             Z
*        51             AY
*        52             AZ
*        80             CB
*        676            YZ
*        702            ZZ
*        705            AAC
*       几个典型值为：
*       Z              26
*       ZZ             702
*       ZZZ            18278
*       ZZZZ           475254
*       ZZZZZ          12356630
*
*
* 当前版本：1.0
* 作者：耿楠
* 完成日期：2022年12月13日
*
* 取代版本：无
* 原作者：
* 完成日期：alpha[
--------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 列名称最大长度(字符数) */
#define MAXLEN 8

/* 函数原型 */
char* get_excel_column_name(char *, int);

int main()
{
    char str[MAXLEN] = {0};
    int idx[] = {26, 51, 52, 80, 676, 701, 702, 705, 18278, 475254, 12356630};
    int i;

    for(i = 0; i < sizeof(idx) / sizeof(idx[0]); i++)
    {
        memset(str, 0, MAXLEN);
        printf("%d---->%s\n", idx[i], get_excel_column_name(str, idx[i]));
    }

    return 0;
}

/*--------------------------------------------------------------------
// 名称：char* get_excel_column_name(char *col_name, int idx)
// 功能：根据传入的列编号生成EXCEL的列名称
// 算法：使用递归实现
//       1、如果编号小于或等于26，则直接转换得到结果(idx - 1 + 'A')。
//       2、如果编号大于26，则使用商(q)和余(r)规则进行进制转换(26进制)。
//          如果余数为0，则有2种可能：
//              如果商为1，则结果为:(26 + r - 1) % 26 + 'A'。
//              如果商不为1，则使用q-1递归，并将(26 + r - 1) % 26 + 'A'追加到结果。
//          如果余数不为0，则使用q递归，并将(26 + r - 1) % 26 + 'A'追加到结果。
// 参数：
//       [char *col_name] --- 结果字符串指针(需要有空间可写)
//       [int idx] ---------- 从1开始计数的excel列编号
// 返回：[char*] --- 结果字符串指针
// 作者：耿楠
// 日期：2022年12月14日
// 参考：https://www.geeksforgeeks.org/find-excel-column-name-given-number/
---------------------------------------------------------------------*/
char *get_excel_column_name(char *col_name, int idx)
{
    int len;
    int i;
    int q, r;
    char *p;

    if(idx < 26)
    {
        /* 清空字符串 */
        len = strlen(col_name);
        for(i = 0; i < len; i++)
        {
            col_name[i] = 0;
        }
        col_name[0] = idx - 1 + 'A';
        return col_name;
    }
    else
    {
        q = (idx / 26); /* 商 */
        r = idx % 26;   /* 余 */

        /* 清空字符串 */
        len = strlen(col_name);
        for(i = 0; i < len; i++)
        {
            col_name[i] = 0;
        }

        if(r == 0)
        {
            if(q == 1)
            {
                len = strlen(col_name);
                col_name[len] = (26 + r - 1) % 26 + 'A';
            }
            else
            {
                p = get_excel_column_name(col_name, q - 1);
                len = strlen(p);
                p[len] = (26 + r - 1) % 26 + 'A';
            }
        }
        else
        {
            p = get_excel_column_name(col_name, q);
            len = strlen(p);
            p[len] = (26 + r - 1) % 26 + 'A';
        }
        return col_name;
    }
}
